﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Reflection;
using System.Linq.Expressions;

namespace msBsc.WebUi
{
    public class DynamicMethodExecutor
    {
        private Func<object, object[], object> m_execute;

        public DynamicMethodExecutor(MethodInfo methodInfo)
        {
            this.m_execute = this.GetExecuteDelegate(methodInfo);
        }

        public object Execute(object instance, object[] parameters)
        {
            return this.m_execute(instance, parameters);
        }

        private Func<object, object[], object> GetExecuteDelegate(MethodInfo methodInfo)
        {
            // parameters to execute
            ParameterExpression instanceParameter =
                Expression.Parameter(typeof(object), "instance");
            ParameterExpression parametersParameter =
                Expression.Parameter(typeof(object[]), "parameters");

            // build parameter list
            List<Expression> parameterExpressions = new List<Expression>();
            ParameterInfo[] paramInfos = methodInfo.GetParameters();
            for (int i = 0; i < paramInfos.Length; i++)
            {
                // (Ti)parameters[i]
                BinaryExpression valueObj = Expression.ArrayIndex(
                    parametersParameter, Expression.Constant(i));
                UnaryExpression valueCast = Expression.Convert(
                    valueObj, paramInfos[i].ParameterType);

                parameterExpressions.Add(valueCast);
            }

            // non-instance for static method, or ((TInstance)instance)
            Expression instanceCast = methodInfo.IsStatic ? null :
                Expression.Convert(instanceParameter, methodInfo.ReflectedType);

            // static invoke or ((TInstance)instance).Method
            MethodCallExpression methodCall = Expression.Call(
                instanceCast, methodInfo, parameterExpressions);

            // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
            if (methodCall.Type == typeof(void))
            {
                Expression<Action<object, object[]>> lambda =
                    Expression.Lambda<Action<object, object[]>>(
                        methodCall, instanceParameter, parametersParameter);

                Action<object, object[]> execute = lambda.Compile();
                return (instance, parameters) =>
                {
                    execute(instance, parameters);
                    return null;
                };
            }
            else
            {
                UnaryExpression castMethodCall = Expression.Convert(
                    methodCall, typeof(object));
                Expression<Func<object, object[], object>> lambda =
                    Expression.Lambda<Func<object, object[], object>>(
                        castMethodCall, instanceParameter, parametersParameter);

                return lambda.Compile();
            }
        }
    }


    public class GridCmdHandler : IHttpHandler,IRequiresSessionState
    {
        public GridCmdHandler()
        {
        }

        public void ProcessRequest(HttpContext context)
        {
            context.Response.Cache.SetNoStore();
            doPageAjax(context);
        }

        private void doPageAjax(HttpContext context)
        { 
            DateTime dtStart1 = DateTime.Now;
            string strPage = "", strParamJson = "", strPostJson = "";
            try
            {

                context.Response.AddHeader("Content-type", "text/javascript");
                string lstr = context.Request.Params["_gt_json"];
                msBsc.AppLogic.Cfg.gtGridCRecord resgtGrid = new msBsc.AppLogic.Cfg.gtGridCRecord(lstr);

                //Response.Expires = -1;
                //Response.CacheControl = "no-cache";   //设置页面无缓存 
                //msBsc.AppLogic.Cfg.UserInfo oUserInfo = new msBsc.AppLogic.Cfg.UserInfo();
                //if (!msBsc.SvRef.UserInfo.Online)
                //    throw new Exception("错误：用户未登录！");

                if (!string.IsNullOrEmpty(resgtGrid.custJSPARAM))
                    strParamJson = resgtGrid.custJSPARAM;
                else if (resgtGrid.parameters["JSPARAM"] != null)
                    strParamJson = resgtGrid.parameters["JSPARAM"].ToString();
                if (!string.IsNullOrEmpty(resgtGrid.custJSPOST))
                    strPostJson = resgtGrid.custJSPOST;
                else if (resgtGrid.parameters["JSPOST"] != null)
                    strPostJson = resgtGrid.parameters["JSPOST"].ToString();

                msBsc.AppLogic.Cfg.SynDictionary htParam = gtJsonTo.GetHashData(strParamJson);
                msBsc.AppLogic.Cfg.SynDictionary htPostData = gtJsonTo.GetHashData(strPostJson);


                if (htParam.ContainsKey("PPAGE"))
                    strPage = htParam["PPAGE"].ToString();
                else if (!string.IsNullOrEmpty(context.Request.Params["PPAGE"]))
                    strPage = context.Request.Params["PPAGE"];
                string strJSon = "";



                //////////////////////////

                //Type t = typeof(msBsc.WebUi.BPage);
                //MethodInfo methodInfo = t.GetMethod("Say");
                //DynamicMethodExecutor executor = new DynamicMethodExecutor(methodInfo); 
                //    executor.Execute(program, parameters); 

                ///////////////////////////

                
                Type otype = Type.GetType(strPage, false, false);
                if (otype != null)
                {
                    using (msBsc.Cls.BPage ocpage = (msBsc.Cls.BPage)Activator.CreateInstance(otype))
                    {
                        ocpage.gtGridRet = resgtGrid;
                        strJSon = ocpage.GetJSon(htParam, htPostData);
                    }
                    GC.Collect();
                }
                else
                {

                    //System.Reflection.Assembly asm = System.Reflection.Assembly.Load("msBsc.WebUi");
                    System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();

                    Type[] types = asm.GetTypes();
                    IEnumerable<Type> asmType =
            types.Where((type, index) => type.Name.ToUpper() == strPage.ToUpper());
                    foreach (Type type in asmType)
                    {
                        using (msBsc.Cls.BPage ocpage = (msBsc.Cls.BPage)type.Assembly.CreateInstance(type.FullName))
                        {
                            try
                            {
                                ocpage.gtGridRet = resgtGrid;
                                strJSon = ocpage.GetJSon(htParam, htPostData);
                                ocpage.Dispose();
                                GC.Collect();
                            }
                            catch (Exception err)
                            {
                                ocpage.Dispose();
                                GC.Collect();
                                throw err;
                            }
                        }
                        break;
                    }
                }
                if (resgtGrid.action != "export")
                    context.Response.Write(strJSon);

                //jqGridID=JQGrid1&_search=false&nd=1270819638406&rows=10&page=2&sidx=&sord=asc

                ////c#后台接收可以不加[]，JS接收必须有[]
                //try
                //{
                //    if (DateTime.Now > dtStart1.AddSeconds(15))
                //    {
                //        UserInfo oUserInfo2 = new UserInfo();
                //        oUserInfo2.LogUserOperate("执行超时gt", strPage + strParamJson
                //            , System.DateTime.Now.ToString()
                //            , System.DateTime.Now.ToString()
                //            , HttpContext.Current.Request.UserHostAddress
                //            , HttpContext.Current.Request.UserHostName
                //            , HttpContext.Current.Request.UserAgent
                //            , (DateTime.Now - dtStart1).TotalSeconds.ToString() + "---" + dtStart1.ToString() + "-->--" + DateTime.Now.ToString());
                //    }
                //}
                //catch
                //{
                //}
            }
            catch (Exception err)
            {
                string strlogin = "";
                if (err.Message.IndexOf("会话或服务器缓存已过期，请重新登录！") != -1)
                {
                    strlogin = ",\"jscrip\":\"window.location.href =window.location.href;\"";
                }
                context.Response.Clear();
                context.Response.Write("[{");
                context.Response.Write(string.Format("\"jmsg\":\"{0}\"", msBsc.AppLogic.Cfg.HttpTools.stringToJson("服务器端错误：" + err.Message + "\r\n错误堆栈：" + err.Source)) + strlogin);
                context.Response.Write("}]");
            }
        }


        public bool IsReusable
        {
            get { return true; }
        }
    }
}